﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Xfs
{
    [XfsObjectSystem]
    public class XfsMoveComponentStartSystem : XfsStartSystem<XfsMoveComponent>
    {
        public override void Start(XfsMoveComponent self)
        {

        }
    }

    [XfsObjectSystem]
    public class XfsMoveComponentUpdateSystem : XfsUpdateSystem<XfsMoveComponent>
    {
        public override void Update(XfsMoveComponent self)
        {

        }
    }

    public static class XfsMoveComponentHelper
    {
        public static async XfsTask MoveToAsync(this XfsMoveComponent self, Vector3 target, CancellationToken cancellationToken)
        {
            /// 新目标点离旧目标点太近，不设置新的
            if ((target - self.Target).sqrMagnitude < 0.01f)
            {
                return;
            }
            /// 距离当前位置太近
            if ((self.GetParent<XfsUnit>().Position - target).sqrMagnitude < 0.01f)
            {
                return;
            }

            self.Target = target;

            /// 开启协程移动
            await self.StartMove(cancellationToken);
        }

        public static async XfsTask StartMove(this XfsMoveComponent self, CancellationToken cancellationToken)
        {
            XfsUnit unit = self.GetParent<XfsUnit>();
            self.StartPos = unit.Position;
            self.StartTime = XfsTimeHelper.Now();
            float distance = (self.Target - self.StartPos).magnitude;
            if (Math.Abs(distance) < 0.1f)
            {
                return;
            }

            self.needTime = (long)(distance / self.Speed * 1000);

            /// 协程如果取消，将算出玩家的真实位置，赋值给玩家
            cancellationToken.Register(() =>
            {
                long timeNow = XfsTimeHelper.Now();
                if (timeNow - self.StartTime >= self.needTime)
                {
                    unit.Position = self.Target;
                }
                else
                {
                    float amount = (timeNow - self.StartTime) * 1f / self.needTime;
                    unit.Position = Vector3.Lerp(self.StartPos, self.Target, amount);
                }

                Console.WriteLine(XfsTimeHelper.CurrentTime() + " " + self.GetType().Name + " 75. Register: Id-P-T-S " + unit.Id + "-" + unit.Position.ToString() + "-" + self.Target.ToString() + "-" + unit.StartPosition.ToString());
            });

            while (true)
            {
                await XfsGame.XfsSence.GetComponent<XfsTimerComponent>().WaitAsync(50, cancellationToken);

                long timeNow = XfsTimeHelper.Now();

                if (timeNow - self.StartTime >= self.needTime)
                {
                    unit.Position = self.Target;
                    break;
                }

                float amount = (timeNow - self.StartTime) * 1f / self.needTime;
                unit.Position = Vector3.Lerp(self.StartPos, self.Target, amount);
            }

            Console.WriteLine(XfsTimeHelper.CurrentTime() + " " + self.GetType().Name + " 95. ToTarget: Id-P-T-S " + unit.Id + "-" + unit.Position.ToString() + "-" + self.Target.ToString() + "-" + unit.StartPosition.ToString());
        }





    }




}
